﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Collections;
using System.Windows.Forms;
using TagCore;

namespace TagManager
{
    public partial class SearchControl : UserControl
    {
        #region Data
        private IMusicQuery mq;
        public event ViewResultsHandler ViewResults;
        #endregion

        #region C'tor
        public SearchControl()
        {
            InitializeComponent();
        }
        #endregion

        #region Public Methods
        public void SetQuery(IMusicQuery mq)
        {
            this.mq = mq;
        }

        public void Update(IMusicData md)
        {
            // uncheck all boxes           
            AlbumCheck(false);
            TitleCheck(false);
            PerformerCheck(false);
            YearCheck(false);

            // update all the data
            txtTitle.Text = md.Title;
            txtArtist.Text = TagCoreUtil.CombineStrings(md.Artists);
            txtYear.Text = md.Year.ToString();
            txtAlbum.Text = md.Album;

            // clear results
            lvResults.Clear();
        }
        #endregion

        #region Private Methods
        private void AlbumCheck(bool b)
        {
            if (chAlbum.Checked != b)
                chAlbum.Checked = b;
            txtAlbum.ReadOnly = !b;
        }

        private void PerformerCheck(bool b)
        {
            if (chPerformer.Checked != b)
                chPerformer.Checked = b;
            txtArtist.ReadOnly = !b;
        }

        private void TitleCheck(bool b)
        {
            if (chTitle.Checked != b)
                chTitle.Checked = b;
            txtTitle.ReadOnly = !b;
        }

        private void YearCheck(bool b)
        {
            if (chYear.Checked != b)
                chYear.Checked = b;
            txtYear.ReadOnly = !b;
        }

        private void ListResults(IMusicData[] results)
        {
            lvResults.Clear();
            ConfigureListView();

            foreach (IMusicData md in results)
            {
                ListViewItem lvi = new ListViewItem(md.Album);
                lvi.Tag = md;
                lvi.SubItems.Add(new ListViewItem.ListViewSubItem(lvi, TagCoreUtil.CombineStrings(md.Artists)));
                lvi.SubItems.Add(new ListViewItem.ListViewSubItem(lvi, md.Title));
                lvResults.Items.Add(lvi);
            }
        }

        private void ConfigureListView()
        {          
            lvResults.HeaderStyle = ColumnHeaderStyle.Clickable;
            lvResults.View = View.Details;
            lvResults.MultiSelect = true;

            ColumnHeader ch = new ColumnHeader();
            ch.Text = "Album";
            ch.Width = 150;
            lvResults.Columns.Add(ch);

            ch = new ColumnHeader();
            ch.Text = "Artist";
            ch.Width = 160;
            lvResults.Columns.Add(ch);

            ch = new ColumnHeader();
            ch.Text = "Title";
            ch.Width = 160;
            lvResults.Columns.Add(ch);
        }

        private object SetSearchData(CheckBox cb, object val, List<QueryFields> fields, QueryFields field)
        {
            if (cb.Checked)
                fields.Add(field);
            return val;
        }

        private QueryFields DoConvert(List<QueryFields> fields)
        {
            QueryFields f = fields[0];
            for (int loop = 1; loop < fields.Count; loop++)
                f |= fields[loop];
            return f;
        }

        private void DoSearch()
        {
            MusicData md = new MusicData();
            List<QueryFields> fields = new List<QueryFields>();

            md.Title   = SetSearchData(chTitle, txtTitle.Text, fields, QueryFields.Title) as string;
            md.Artists = SetSearchData(chPerformer, TagCoreUtil.SplitStrings(txtArtist.Text), fields, QueryFields.Artist) as string[];
            md.Year = Convert.ToUInt32(SetSearchData(chYear, txtYear.Text, fields, QueryFields.Year));
            md.Album = SetSearchData(chAlbum, txtAlbum.Text, fields, QueryFields.Album) as string;

            if (fields.Count > 0)
            {
                ListResults(mq.Search(md, DoConvert(fields)));
                // Auto view if possible
                DoResults();
            }
        }

        private void DoResults()
        {
            IList lvic = null;
            if (lvResults.SelectedItems.Count == 0)
            {
                if (lvResults.Items.Count < 6)
                    lvic = lvResults.Items;
                else
                {
                    // return top 5
                    lvic = new List<ListViewItem>();
                    for (int loop = 0; loop < 5; loop++)
                        lvic.Add(lvResults.Items[loop]);
                }
            }
            else if (lvResults.SelectedItems.Count < 6)
                lvic = lvResults.SelectedItems;

            if (lvic != null)
            {
                List<IMusicData> results = new List<IMusicData>();
                foreach (ListViewItem lvi in lvic)
                    results.Add(lvi.Tag as IMusicData);

                if (ViewResults != null)
                    ViewResults(this, new ResultsEventArgs(results.ToArray()));
            }
            else
            {
                // error
            }
        }
        #endregion

        #region Private Handlers
        private void chTitle_CheckedChanged(object sender, EventArgs e)
        {
            TitleCheck(chTitle.Checked);
        }

        private void chPerformer_CheckedChanged(object sender, EventArgs e)
        {
            PerformerCheck(chPerformer.Checked);
        }

        private void chAlbum_CheckedChanged(object sender, EventArgs e)
        {
            AlbumCheck(chAlbum.Checked);
        }

        private void chYear_CheckedChanged(object sender, EventArgs e)
        {
            YearCheck(chYear.Checked);
        }

        private void pbSearch_Click(object sender, EventArgs e)
        {
            DoSearch();           
        }

        private void lvResults_DoubleClick(object sender, System.EventArgs e)
        {
            if (lvResults.SelectedItems.Count > 0)
            {
                ListViewItem lvi = lvResults.SelectedItems[0];
                if (ViewResults != null)
                    ViewResults(this, new ResultsEventArgs(new IMusicData[] { lvi.Tag as IMusicData } ));
            }
        }

        private void pbView_Click(object sender, EventArgs e)
        {
            DoResults();
        }
        #endregion
    }
}